﻿using JinYuan.Helper;
using JinYuan.Models;
using JinYuan.VirtualDataLibrary;
using Language;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace LargeSquareOne
{


    public partial class FrmMonitor : MultiLanguageForm
    {
        private static readonly object uiLock = new object();
        private static FrmMonitor _instance;
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();
        private readonly PrivateFontCollection _font = new PrivateFontCollection();
        private Font _myFont;

        public static FrmMonitor Instance
        {
            get
            {
                lock (uiLock)
                {
                    return _instance ??= new FrmMonitor();
                }
            }
        }

        public FrmMonitor()
        {
            InitializeComponent();
            InitializeFormSettings();
            //LoadCustomFont();

            this.FormClosing += FrmMonitor_FormClosing;
        }

        private void InitializeFormSettings()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                         ControlStyles.DoubleBuffer |
                         ControlStyles.ResizeRedraw |
                         ControlStyles.Selectable |
                         ControlStyles.SupportsTransparentBackColor, true);
        }

        private void LoadCustomFont()
        {
            try
            {
                var fontPath = Path.Combine(Environment.CurrentDirectory, "Assts", "Fonts", "FZY4JW.ttf");
                _font.AddFontFile(fontPath);
                var myFontFamily = new FontFamily(_font.Families[0].Name, _font);
                _myFont = new Font(myFontFamily, 20, FontStyle.Bold);
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "加载字体异常".Translated() + $"：{ex.Message}");
            }
        }

        private void FrmMonitor_FormClosing(object sender, FormClosingEventArgs e)
        {
            _cts.Cancel();
            _font?.Dispose();
            _myFont?.Dispose();
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0014) return; // 禁掉清除背景消息
            base.WndProc(ref m);
        }

        private async void FrmMonitor_Load(object sender, EventArgs e)
        {
            try
            {
                SetChart();
                await RefreshAllDataAsync();
                await StartPeriodicRefreshAsync(_cts.Token);
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "窗体加载异常".Translated() + $"：{ex.Message}");
            }
        }

        private void SetChart()
        {
            try
            {
                #region 24小时统计
                Chart12HourTotal.Series.Clear();
                Chart12HourTotal.ChartAreas[0].AxisY.Minimum = 0;
                Chart12HourTotal.ChartAreas[0].AxisY.Maximum = 2000;

                ChartHelper.AddSeries(Chart12HourTotal, "投入".Translated(), SeriesChartType.Column,
                    ChartValueType.Auto, MarkerStyle.Diamond, 8, Color.DarkTurquoise,
                    Color.Aqua, "", false, true);

                ChartHelper.AddSeries(Chart12HourTotal, "产出".Translated(), SeriesChartType.Column,
                    ChartValueType.Auto, MarkerStyle.Diamond, 8, Color.PaleGoldenrod,
                    Color.PaleGoldenrod, "", false, true);

                ChartHelper.AddSeries(Chart12HourTotal, "优率".Translated(), SeriesChartType.Spline,
                    ChartValueType.String, MarkerStyle.Circle, 8, Color.Lime,
                    Color.Lime, "#VAL{P}", true, true);

                ChartHelper.SetStyle(Chart12HourTotal, Color.Transparent, Color.White);
                ChartHelper.SetLegend(Chart12HourTotal, Docking.Left, StringAlignment.Center,
                    Color.Transparent, Color.White);
                ChartHelper.SetXY(Chart12HourTotal, "时间".Translated(), "数值".Translated(), -45, StringAlignment.Center,
                    Color.White, Color.White, AxisArrowStyle.None, 1, true);
                ChartHelper.SetMajorGrid(Chart12HourTotal, Color.Transparent, 20, 2);
                #endregion
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "图表初始化异常".Translated() + $"：{ex.Message}");
            }
        }

        private async Task StartPeriodicRefreshAsync(CancellationToken ct)
        {
            while (!ct.IsCancellationRequested)
            {
                try
                {
                    await RefreshAllDataAsync();
                    await Task.Delay(2000, ct);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    CommonMethods.AddLog(true, "定时刷新异常".Translated() + $"：{ex.Message}");
                    await Task.Delay(1000, ct);
                }
            }
        }

        private async Task RefreshAllDataAsync()
        {
            var tasks = new[]
            {
            Refish12ProdQtyAsync(),
            RefreshXiaoLvDataAsync(),
            RefreshChatTop10AlarmDataAsync(),
            RefreshChatNGDataAsync()
        };

            await Task.WhenAll(tasks);
        }

        private async Task Refish12ProdQtyAsync()
        {
            await Task.Run(() =>
            {
                if (IsDisposed) return;

                this.InvokeIfRequired(() =>
                {
                    var data = CommonMethods.Lst_Prod12HourData?.Count > 0 ? CommonMethods.Lst_Prod12HourData : MockDataGenerator.Generate12HourData();

                    UpdateChart12HourData(data);
                });
            });
        }

        private void UpdateChart12HourData(List<Chart12HourData> data)
        {
            try
            {
                var maxValue = data.Max(x => x.ProdIn);
                Chart12HourTotal.ChartAreas[0].AxisY.Minimum = 0;
                Chart12HourTotal.ChartAreas[0].AxisY.Maximum = (int)maxValue + 1500;

                // 直接使用数据，不需要额外排序
                var x1 = data.Select(c => c.DisplayTime).ToList();
                var y1 = data.Select(c => c.ProdIn).ToList();
                var y2 = data.Select(c => c.ProdOut).ToList();
                var y3 = data.Select(c => c.OKRatio).ToList();

                Chart12HourTotal.Series[0].Points.DataBindXY(x1, y1);
                Chart12HourTotal.Series[1].Points.DataBindXY(x1, y2);
                Chart12HourTotal.Series[2].Points.DataBindXY(x1, y3);

                // 设置X轴标签的角度，提高可读性
                Chart12HourTotal.ChartAreas[0].AxisX.LabelStyle.Angle = 0;
                // 确保显示所有标签
                Chart12HourTotal.ChartAreas[0].AxisX.Interval = 1;
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新12小时数据异常".Translated() + $"：{ex.Message}");
            }
        }


        // 效率数据也可以添加模拟数据
        private async Task RefreshXiaoLvDataAsync()
        {
            await Task.Run(() =>
            {
                if (IsDisposed) return;

                // 使用实际数据或模拟数据
                var utilizationRate = CommonMethods.JiaDL >= 0
                    ? Convert.ToDouble(CommonMethods.JiaDL) * 100
                    : MockDataGenerator._random.Next(60, 95);

                var totalQty = CommonMethods.TotalQty >= 0
                    ? CommonMethods.TotalQty
                    : MockDataGenerator._random.Next(1000, 5000);

                var okQty = CommonMethods.ProOKQty >= 0
                    ? CommonMethods.ProOKQty
                    : MockDataGenerator._random.Next(900, (int)totalQty);

                var yieldRate = totalQty == 0 ? 0 :
                    Convert.ToDouble((Convert.ToDouble(okQty) /
                                    Convert.ToDouble(totalQty) * 100.0)
                        .ToString("f2"));

                this.InvokeIfRequired(() =>
                {
                    UpdateEfficiencyControls(utilizationRate, yieldRate, (int)totalQty, (int)okQty);
                    UpdateTimeDisplay();
                    UpdateEnergyDisplay();
                });
            });
        }

        private double CalculateYieldRate()
        {
            if (CommonMethods.TotalQty == 0) return 0;

            return Convert.ToDouble((Convert.ToDouble(CommonMethods.ProOKQty) /
                                   Convert.ToDouble(CommonMethods.TotalQty) * 100.0)
                .ToString("f2"));
        }

        private void UpdateEfficiencyControls(double utilizationRate, double yieldRate, int totalQty, int okQty)
        {
            try
            {
                titleModeName.Title = CommonMethods.mesConfig.ModelName ?? "测试型号";
                titleFactory_code.Title = CommonMethods.mesConfig.siteCode ?? "TEST001";
                titleLine_No.Title = CommonMethods.mesConfig.lineCode ?? "LINE01";
                titleEqp_code.Title = CommonMethods.mesConfig.equipNum ?? "EQP001";
                proUtilizationRate.FloatValue = (float)utilizationRate;
                proPPM.IntValue = (int)(CommonMethods.Ppm > 0 ? CommonMethods.Ppm : MockDataGenerator._random.Next(100, 1000));
                proOKQty.IntValue = okQty;
                proOKRatio.Value = yieldRate;
                proTotalQty.TotalValue = totalQty;
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新效率控件异常".Translated() + $"：{ex.Message}");
            }
        }

        private void UpdateTimeDisplay()
        {
            try
            {
                if (CommonMethods.PlcOpenAndRunTime?.Count > 0)
                {
                    titleStartTime.Title = $"{CommonMethods.PlcOpenAndRunTime[0]}:" +
                                         $"{CommonMethods.PlcOpenAndRunTime[1]}:" +
                                         $"{CommonMethods.PlcOpenAndRunTime[2]}";

                    titleRunTime.Title = $"{CommonMethods.PlcOpenAndRunTime[3]}:" +
                                       $"{CommonMethods.PlcOpenAndRunTime[4]}:" +
                                       $"{CommonMethods.PlcOpenAndRunTime[5]}";
                }
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新时间显示异常".Translated() + $"：{ex.Message}");
            }
        }

        private void UpdateEnergyDisplay()
        {
            try
            {
                if (CommonMethods.listElectricEnergy?.Count > 0)
                {
                    EyMaterH1.ElectricEnergy = CommonMethods.listElectricEnergy[0];
                }
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新能源显示异常".Translated() + $"：{ex.Message}");
            }
        }

        private async Task RefreshChatTop10AlarmDataAsync()
        {
            await Task.Run(() =>
            {
                if (IsDisposed) return;

                this.InvokeIfRequired(() =>
                {
                    UpdateAlarmChart();
                });
            });
        }

        private void UpdateAlarmChart()
        {
            try
            {
                var alarmData = CommonMethods.Lst_AlarmTop10_Qty?.Count > 0
                    ? CommonMethods.Lst_AlarmTop10_Qty
                    : MockDataGenerator.GenerateAlarmTop10Data();

                if (alarmData?.Count > 0)
                {
                    chartAlarmData.Series.Clear();
                    chartAlarmData.Titles.Clear();

                    var maxValue = alarmData.Max(x => x.DataCount);
                    chartAlarmData.ChartAreas[0].AxisY.Minimum = 0;
                    chartAlarmData.ChartAreas[0].AxisY.Maximum = (int)maxValue + 20;

                    foreach (var item in alarmData)
                    {
                        ChartHelper.AddSeries(chartAlarmData, item.DataType,
                            SeriesChartType.Column, ChartValueType.Auto,
                            MarkerStyle.Diamond, 4, Color.DarkTurquoise,
                            Color.White, "", false, true);
                    }

                    ConfigureAlarmChart();

                    var xData = alarmData.Select(c => c.DataType).ToList();
                    var yData = alarmData.Select(c => c.DataCount).ToList();
                    chartAlarmData.Series[0].Points.DataBindXY(xData, yData);
                }
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新报警图表异常".Translated() + $"：{ex.Message}");
            }
        }

        private void ConfigureAlarmChart()
        {
            ChartHelper.SetTitle(chartAlarmData, "报警TOP10".Translated(),
                new Font("微软雅黑", 12), Docking.Top, Color.White);
            ChartHelper.SetStyle(chartAlarmData, Color.Transparent, Color.White);
            ChartHelper.SetLegend(chartAlarmData, Docking.Top,
                StringAlignment.Center, Color.Transparent, Color.White);
            ChartHelper.SetXY(chartAlarmData, "报警项".Translated(), "次数".Translated(), -45,
                StringAlignment.Center, Color.White, Color.White,
                AxisArrowStyle.None, 1, false);
            ChartHelper.SetMajorGrid(chartAlarmData, Color.Transparent, 20, 2);
        }

        private void BindAlarmChartData()
        {
            var xData = CommonMethods.Lst_AlarmTop10_Qty.Select(c => c.DataType).ToList();
            var yData = CommonMethods.Lst_AlarmTop10_Qty.Select(c => c.DataCount).ToList();
            chartAlarmData.Series[0].Points.DataBindXY(xData, yData);
        }

        private async Task RefreshChatNGDataAsync()
        {
            await Task.Run(() =>
            {
                if (IsDisposed) return;

                this.InvokeIfRequired(() =>
                {
                    UpdateNGChart();
                });
            });
        }

        private void UpdateNGChart()
        {
            try
            {
                var ngData = CommonMethods.Lst_DefectTypeQty?.Count > 0
                    ? CommonMethods.Lst_DefectTypeQty
                    : MockDataGenerator.GenerateNGData();

                if (ngData?.Count > 0)
                {
                    chartNgShow.Series.Clear();
                    chartNgShow.Titles.Clear();

                    var maxValue = ngData.Max(x => x.DataCount);
                    chartNgShow.ChartAreas[0].AxisY.Minimum = 0;
                    chartNgShow.ChartAreas[0].AxisY.Maximum = (int)maxValue + 100;

                    foreach (var item in ngData)
                    {
                        ChartHelper.AddSeries(chartNgShow, item.DataType,
                            SeriesChartType.Column, ChartValueType.Auto,
                            MarkerStyle.Diamond, 4, Color.Red,
                            Color.White, "", false, true);
                    }

                    ConfigureNGChart();

                    var xData = ngData.Select(c => c.DataType).ToList();
                    var yData = ngData.Select(c => c.DataCount).ToList();
                    chartNgShow.Series[0].Points.DataBindXY(xData, yData);
                }
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "更新不良图表异常".Translated() + $"：{ex.Message}");
            }
        }

        private void ConfigureNGChart()
        {
            ChartHelper.SetTitle(chartNgShow, "各不良项".Translated(),
                new Font("微软雅黑", 12), Docking.Top, Color.White);
            ChartHelper.SetStyle(chartNgShow, Color.Transparent, Color.White);
            ChartHelper.SetLegend(chartNgShow, Docking.Top,
                StringAlignment.Center, Color.Transparent, Color.White);
            ChartHelper.SetXY(chartNgShow, "项名".Translated(), "数值".Translated(), 0,
                StringAlignment.Center, Color.White, Color.White,
                AxisArrowStyle.None, 1, false);
            ChartHelper.SetMajorGrid(chartNgShow, Color.Transparent, 1, 1);
        }

        private void BindNGChartData()
        {
            var xData = CommonMethods.Lst_DefectTypeQty.Select(c => c.DataType).ToList();
            var yData = CommonMethods.Lst_DefectTypeQty.Select(c => c.DataCount).ToList();
            chartNgShow.Series[0].Points.DataBindXY(xData, yData);
        }
    }

    // 扩展方法
    public static class ControlExtensions
    {
        public static void InvokeIfRequired(this Control control, Action action)
        {
            if (control.IsDisposed) return;

            if (control.InvokeRequired)
                control.BeginInvoke(action);
            else
                action();
        }
    }

}